package miniBanco.Mapper;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

import basics.DBManager;
import miniBanco.Core.Cliente;
import miniBanco.Core.Cuenta;
import miniBanco.Core.DomainObject;
import miniBanco.Exceptions.HandledException;
import miniBanco.Mapper.Interface.IClienteFinder;
import miniBanco.Mapper.Interface.IstatementSource;

public class ClienteMapper extends AbstractMapper implements IClienteFinder {
	private static final String TAG = ClienteMapper.class.getSimpleName();
	public static final String IDCOLUMN = "id";
	public static final String COLUMNS = "Dni,Nombre,Cuit,Activo,NroCliente,TipoCliente";
	
	protected StringBuilder findStatement()
	{
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT "+IDCOLUMN+","+COLUMNS+
				" FROM "+ getTableName()+
				" WHERE NroCliente = %d AND TipoCliente = 1");
		return sb;
	}
	
	private StringBuilder findAllStatement()
	{
		StringBuilder sb = new StringBuilder();
		sb.append("SELECT "+IDCOLUMN+","+COLUMNS+
				" FROM "+ getTableName()+"");
		return sb;
	}
	
	public ArrayList<Cliente> findAll()
	{
		StringBuilder findStatement = findAllStatement();
		ResultSet rs = sqlHelper.ExecuteQuery(findStatement.toString(), TAG);
		ArrayList<Cliente> clienteList = new ArrayList<Cliente>();
		try {
			while(rs.next())
			{
				Cliente cli = (Cliente) load(rs);
				clienteList.add(cli);
			}
		} catch (Exception e) {
			DBManager.Error(e);
			throw new HandledException("Se produjo un error inesperado. Ver log. Error="+e.getMessage());
		}
		return clienteList;
	}
	
	public Cliente find(long id)
	{
		return (Cliente) abstractFind(id);
	}
	@Override
	protected DomainObject doLoad(long id, ResultSet rs) throws SQLException {
		id = rs.getLong(1);
		int dni = rs.getInt(2);
		String nombre = rs.getString(3);
		int cuit = rs.getInt(4);
		int nroCliente = rs.getInt(6);
		Cliente cliente = new Cliente(nroCliente);
		cliente.setNombre(nombre);
		cliente.setDni(dni);
		cliente.setCuit(cuit);
		cliente.setID(id);
		
		DBManager.Log(TAG,"Load Cliente||ID:"+id+"||nroCliente:"+nroCliente+"||nombre"+nombre );
		mapperRegistry.CuentaMapper().findAllFor(cliente);
		return cliente;
	}
	private StringBuilder insertStatement() {
		StringBuilder sb = new StringBuilder();
		sb.append("INSERT INTO "+getTableName()+" ("+COLUMNS+")  VALUES (%d,'%s',%d,%d,%d,1)");
		return sb;
	}
	@Override 
	protected StringBuilder doInsert(DomainObject subject) {
		Cliente c = (Cliente) subject;
		String sql = String.format(insertStatement().toString(),c.getDni(),c.getNombre(),c.getCuit(),1,c.getNroCliente());
		StringBuilder insertStatement = new StringBuilder();
		insertStatement.append(sql);
		return insertStatement;
	}
	@Override
	protected String getTableName() {
		return "Cliente";
	}
	@SuppressWarnings("unchecked")
	public ArrayList<Cliente> findByNombre(String nombre)
	{
		return (ArrayList<Cliente>)findMany(new FindByName(nombre));
	}
	static class FindByName implements IstatementSource
	{
		String nombre;
		public FindByName(String nombre)
		{
			this.nombre = nombre;
		}
		@Override
		public String sql() {
			StringBuilder sb = new StringBuilder();
			sb.append("SELECT "+IDCOLUMN+","+COLUMNS+
					" FROM CLIENTE"+
					" WHERE Nombre = '%s' AND TipoCliente = 1");
			return sb.toString();
			
		}

		@Override
		public Object[] parameters() {
			Object[] result = {nombre};
			return result;
		}
		
	}

	@Override
	public void doSave(DomainObject subject) {
		Cliente cliente = (Cliente) subject;
		for(Cuenta cuenta:cliente.getCuentas()){
			mapperRegistry.CuentaMapper().doSave(cuenta);
		}
		save(cliente);
	}

	@Override
	public void doDelete(DomainObject subject) {
		Cliente cliente = (Cliente) subject;
		for(Cuenta cuenta:cliente.getCuentas()){
			mapperRegistry.CuentaMapper().delete(cuenta);
		}
		delete(cliente);
	}

	@Override
	protected StringBuilder doUpdate(DomainObject subject) {
		Cliente cliente = (Cliente) subject;
		StringBuilder sb = new StringBuilder();
		sb.append("UPDATE "+getTableName()+" SET Dni = "+cliente.getDni()+", "
				+ "Nombre = '"+cliente.getNombre()+"', "
				+ "Cuit ="+cliente.getCuit()+""
				+ "Where ID="+subject.getID());
		return sb;
	}

}